package com.etone.smartAudit.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.http.HtmlUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.etone.smartAudit.commService.CommPUumUserinfoService;
import com.etone.smartAudit.domain.*;
import com.etone.smartAudit.dto.PortalPushDTO;
import com.etone.smartAudit.dto.certificate.*;
import com.etone.smartAudit.dto.egcc.MsgDTO;
import com.etone.smartAudit.dto.email.EmailDTO;
import com.etone.smartAudit.error.CustomParameterizedException;
import com.etone.smartAudit.mapper.AdminMapper;
import com.etone.smartAudit.mapper.CertificateFileMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etone.smartAudit.security.SecurityUtils;
import com.etone.smartAudit.security.jwt.TokenProvider;
import com.etone.smartAudit.vo.admin.AdminVO;
import com.etone.smartAudit.vo.certificate.CertificateVo;
import com.etone.smartAudit.vo.PagerVO;
import com.etone.smartAudit.vo.certificate.CertificateVoDetail;
import com.etone.smartAudit.vo.certificate.PersonLoginInfo;
import com.etone.smartAudit.vo.email.EmailContent;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <p>
 * 存证单表  服务实现类
 * </p>
 *
 * @author jiayen
 * @since 2021-06-08
 */
@Slf4j
@Service
public class CertificateFileService extends ServiceImpl<CertificateFileMapper, CertificateFile> {

    public final static int CODE_LENGTH = 8;

    @Autowired
    private CertificatePersonService personService;


    @Autowired
    private CertificateGroupService groupService;

    @Autowired
    private CertificatePersonInfoService infoService;

    //
    @Autowired
    private AdminService adminService;

    @Autowired
    private CertificateGroupAdminService groupAdminService;


    @Autowired
    private CertificateUploadFileService certificateUploadFileService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private BSNService bsnService;

    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private CertificateMemberService memberService;
    @Autowired
    private FileUploadService fileUploadService;


    @Autowired
    private CertificateFileApproval fileApproval;

    @Autowired
    private EGCCMService egccmService;

    @Autowired
    private ItemService itemService;

    @Autowired
    private AdminPermissionService adminPermissionService;


    @Autowired
    private ProjectFileService projectFileService;

    @Autowired
    private EmailContentFormat emailContentFormat;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private TokenProvider tokenProvider;


    @Autowired
    private CommPUumUserinfoService pUumUserinfoService;

    @Value("${egc.file_host:''}")
    private String host;

    /***
     * 添加存证单
     * @param admin
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    public void addCetificateFile(Admin admin, AddCertificateDTO dto) {
        //防止表单重复提交 设置在3秒内
        String key = DigestUtil.md5Hex(JSON.toJSONString(dto));
        String cache = redisUtil.get(key);
        if (StrUtil.isNotEmpty(cache)) {
            throw new CustomParameterizedException("该单正在提交中，请不要重复提交");
        } else {
            redisUtil.setEx(key, "1", 4, TimeUnit.SECONDS);
        }

        CertificateFile certificateFile = new CertificateFile();
        List<CertificateFile> cerList = new ArrayList<>();
        BeanUtils.copyProperties(dto, certificateFile);
        boolean addFlag = true;
        if (dto.getId() != null) {

            addFlag = false;
            CertificateFile updateCer = this.getById(dto.getId());

            if (updateCer.getCheckStatus() == 1 && certificateFile.getState() == CertificateFile.STATE_HANDING) {
                throw new CustomParameterizedException("审核完成，暂时不能修改");
            }

            if (updateCer.getCheckStatus() == null && updateCer.getCheckStatus() == 2) {
                updateCer.setCheckStatus(0);
            }
            //设置缺少数据
            certificateFile.setHandPersonId(updateCer.getHandPersonId());
            dto.setHandPersonId(updateCer.getHandPersonId());
            certificateFile.setCreateBy(updateCer.getCreateBy());
            certificateFile.setId(updateCer.getId());
            //更新   是否有权限更新  创建人可修改
            if (!admin.isAdmin()) {
                if (admin.getId() == null || !admin.getId().equals(certificateFile.getCreateBy())) {
                    throw new CustomParameterizedException("没有该单修改权限!");
                }
            }
            List<CertificatePerson> list = personService.getListByFileIdAndType(dto.getId(), CertificatePerson.YET_READ, CertificatePerson.YES_AGREE, CertificatePerson.NO_AGREE);
            if (!admin.isAdmin()) {
                if (CollectionUtil.isNotEmpty(list)) {
                    throw new CustomParameterizedException("该单已经在执行中，不能修改!");
                }
            }
            certificateFile.setLastDate(LocalDateTime.now());
            certificateFile.setLastHandAdminId(admin.getId());
//            certificateFile.setVersion(updateCer.getVersion() + 1);
            //修改执行人
            Integer handPersonId = certificateFile.getHandPersonId();
            CertificatePerson handPerson = personService.getById(handPersonId);
            if (handPerson != null) {
                Integer personInfoId = handPerson.getPersonInfoId();
                if (dto.getHandPersonId() != null && !dto.getHandPersonId().equals(personInfoId)) {
                    if (dto.getHandPersonInfoId() == null) {
                        dto.setHandPersonInfoId(Integer.valueOf(dto.getHandPersonInfoIds()));
                    }
                    CertificatePersonInfo personInfo = infoService.getById(dto.getHandPersonInfoId());
                    handPerson.setPhone(personInfo.getPhone());
                    handPerson.setEmail(personInfo.getEmail());
                    handPerson.setName(personInfo.getName());
                    handPerson.setIsFirst(true);
                    handPerson.setPersonInfoId(dto.getHandPersonInfoId());
                    personService.updateById(handPerson);
                }
            }
            baseMapper.updateById(certificateFile);
        } else {
            //判断当前项目下该工单名称是否已经存在
            LambdaQueryWrapper<CertificateFile> query = new LambdaQueryWrapper<>();
            query.eq(CertificateFile::getItemId, dto.getItemId())
                    .in(CertificateFile::getName, dto.getName(), dto.getName() + "001");
            List<CertificateFile> exsitList = this.list(query);
            //获取类型
            Integer type = dto.getType();
            if (CollectionUtil.isNotEmpty(exsitList) && type != null && type.equals(CertificateFile.NEED_TYPE)) {
                throw new CustomParameterizedException("该工单名称已经存在，请修改名称！");
            }


            certificateFile.setState(CertificateFile.STATE_HANDING);
            certificateFile.setLastDate(LocalDateTime.now());
            //获取上一次的lastFileId
            Integer lastFileId = dto.getLastFileId();
            if (lastFileId == null) {
                certificateFile.setFileGroupId(IdUtil.fastSimpleUUID());
                certificateFile.setVersion(1.0);
            } else {
                CertificateFile lastFile = lastVersionFile(lastFileId);// this.getById(lastFileId);
                if (lastFile != null) {
                    certificateFile.setFileGroupId(lastFile.getFileGroupId());
                    certificateFile.setVersion((lastFile.getVersion() == null ? 0.0 : lastFile.getVersion()) + 1);
                    certificateFile.setName(lastFile.getName());
                } else {
                    certificateFile.setFileGroupId(IdUtil.fastSimpleUUID());
                    certificateFile.setVersion(1.0);

                }
            }
            //如果是内审部或者是超级管理员则为审核通过 TODO  需求单则直接通过
            if (hasCheckouPermission(admin) || CertificateFile.NEED_TYPE.equals(certificateFile.getType())) {
                certificateFile.setCheckStatus(1);

            } else {
                certificateFile.setCheckStatus(0);
            }
            certificateFile.setCreateTime(LocalDateTime.now());
            certificateFile.setCreateBy(admin.getId());

            String handPersonIds = dto.getHandPersonInfoIds();
            if (StrUtil.isEmpty(handPersonIds)) {
                throw new CustomParameterizedException("执行人不能为空");
            }
            //增加抄送人员
            String copySendPersonIds = dto.getCopySendPersonInfoIds();
            certificateFile.setCopySendPersonInfoIds(copySendPersonIds);


            if (certificateFile.getCheckStatus().equals(1)) {
                //说明有多个
                String[] personIds = handPersonIds.split(",");
                String oldName = certificateFile.getName();
                int size = personIds.length;
                if (size > 1) {
                    for (int i = 0; i < size; i++) {
                        if (StrUtil.isNotEmpty(personIds[i])) {
                            certificateFile.setFileGroupId(IdUtil.fastSimpleUUID());
                            certificateFile.setName(oldName + "00" + (i + 1));
                            dto.setHandPersonInfoId(Integer.valueOf(personIds[i]));
                            saveCerFile(certificateFile, dto, cerList);
                        }
                    }
                } else {
                    if (size > 0) {
                        dto.setHandPersonInfoId(Integer.valueOf(personIds[0]));
                        saveCerFile(certificateFile, dto, cerList);
                    }
                }

            } else {
                saveCerFile(certificateFile, dto, cerList);
            }
        }
        //如果是确认单并且是审核通过的则需要发送5G短信
//        if (CertificateFile.CONFIRM_TYPE.equals(certificateFile.getType()) && certificateFile.getCheckStatus() == 1) {
        if (certificateFile.getCheckStatus() == 1) {
            cerList.forEach(cer -> {
                Integer personId = cer.getHandPersonId();
                if (personId != null) {
                    CertificatePerson person = personService.getById(personId);
                    if (person != null && cer.getCheckStatus() == 1) {
//                        egccmService.sendEmsg(person.getPhone(), person.getCode(), person.getUrl());
                        sendMsg(person, 0);
                    }
                }
            });
        }

        cerList.forEach(cer -> {
            //保存文件
            certificateUploadFileService.saveFile(dto.getFiles(), cer.getId(), CertificateUploadFile.CERTIFICATE_FILE);
        });

        //添加人员到群组
        // 1.审计成员，2-事务所组长 3-质检员 4-审核人  5-复核人员
        addMemberToGroup(dto);
        //处理成功删除临时文件
        fileUploadService.deleteFileByFileVO(dto.getFiles(), false, true);

        //添加则执行抄送，修改的话需要判断是否是有变动的抄送,抄送过的人是否还要抄送
        if (addFlag) {
            cerList.stream().forEach(cer -> {
                if (cer.getCheckStatus().equals(1)) {
                    //审核通过的则执行抄送
                    copySendMsg(cer);
                }
            });
        }
    }


    /***
     * 执行抄送
     */
    public void copySendMsg(CertificateFile certificateFile, CertificatePerson handPerson) {
        //获取抄送id
        String copySendPersonIds = certificateFile.getCopySendPersonInfoIds();
        if (StrUtil.isNotEmpty(copySendPersonIds)) {
            String[] ids = copySendPersonIds.split(",");
            for (int i = 0; i < ids.length; i++) {
                String id = ids[i];
                if (StrUtil.isNotEmpty(id)) {
                    Integer copyId = Integer.valueOf(id);
                    //获取执行人信息
                    AddCertificateDTO addCertificateDTO = new AddCertificateDTO();
                    addCertificateDTO.setHandPersonInfoId(copyId);
                    CertificatePerson person = getHandPerson(addCertificateDTO);
                    person.setCerFileid(certificateFile.getId());
//                  3表示抄送对象 没有执行权限
                    person.setType(3);
                    //设置抄送人员id
                    if (handPerson == null) {
//                        Admin admin = adminService.get(certificateFile.getAdminId());
                        // 获取当前登录用户
                        String loginAdminName = SecurityUtils.getCurrentUserLogin();
                        Admin admin = adminMapper.findByAccount(loginAdminName);
                        if (admin != null) {
                            //说明是发起人抄送
                            person.setOptionPersonId(certificateFile.getAdminId());
                            person.setOptionPersonName(admin.getNickName());
                        }

                    } else {
                        //执行人发送
                        person.setOptionPersonId(handPerson.getId());
                        person.setOptionPersonName(handPerson.getName());
                    }
                    personService.save(person);
                    //执行发送信息
                    if (person != null) {

                        sendMsg(person, 1);
                    }
                }
            }
        }
    }

    /***
     * 执行抄送
     */
    public void copySendMsg(CertificateFile certificateFile) {
        copySendMsg(certificateFile, null);
    }

    /***
     * 执行保存
     * @param certificateFile
     * @param dto
     * @param cerList
     */
    private void saveCerFile(CertificateFile file, AddCertificateDTO dto, List<CertificateFile> cerList) {
        CertificateFile certificateFile = new CertificateFile();
        BeanUtils.copyProperties(file, certificateFile);
        //插入
        if (certificateFile.getId() == null) {
            baseMapper.insert(certificateFile);
        }
        //获取执行人信息
        dto.setHandVersion(1);
        //审核完成才有执行人
        if (file.getCheckStatus() == 1) {
            CertificatePerson person = getHandPerson(dto);
            person.setCerFileid(certificateFile.getId());
            person.setIsFirst(true);
            personService.save(person);
            certificateFile.setHandPersonId(person.getId());
        }
        certificateFile.setHandPersonIds(dto.getHandPersonInfoIds());
        baseMapper.updateById(certificateFile);
        cerList.add(certificateFile);
    }

    /**
     * 判断是否有审计权限
     *
     * @param admin
     * @return
     */
    private boolean hasCheckouPermission(Admin admin) {
        try {
            return admin.isAdmin() || "R_AUDIT".equals(admin.getRole().getCode());
        } catch (Exception e) {
            log.error("获取审计权限失败:hasCheckouPermission", e);
        }
        return false;
    }

    /***
     * 获取确认单最后一个版本号
     * @param fileId
     * @return
     */
    public CertificateFile lastVersionFile(Integer fileId) {
//        CertificateFile file = baseMapper.getLastVersionFile(fileId);
        CertificateFile file = baseMapper.selectById(fileId);
        if (file == null) {
            file = new CertificateFile();
        }
        return file;
    }

    /***
     * 添加人员到群组
     * @param dto
     */
    private void addMemberToGroup(AddCertificateDTO dto) {
        // 1.审计成员，2-事务所组长 3-质检员 4-审核人  5-复核人员
        CertificateGroup group = groupService.getById(dto.getGroupId());
        if (group == null) {
            throw new CustomParameterizedException("请选择正确的群组");
        }
        List<Integer> auditPersons = dto.getAutditPersons();
        if (CollectionUtil.isNotEmpty(auditPersons)) {
            auditPersons.stream().forEach(id -> {
                groupAdminService.saveOrupdateAdmin(id, dto.getGroupId());
            });
        }

        //事务所组长
        groupAdminService.saveOrupdateAdmin(dto.getLeaderAdminId(), dto.getGroupId());
        //质检员
        groupAdminService.saveOrupdateAdmin(dto.getCheckAdminId(), dto.getGroupId());
        //审核人
        groupAdminService.saveOrupdateAdmin(dto.getAuditPersonId(), dto.getGroupId());
        //复核人员
        groupAdminService.saveOrupdateAdmin(dto.getRecheckAdminId(), dto.getGroupId());
    }


    /***
     * 生成执行人信息
     * @param dto
     * @return
     */
    public CertificatePerson getHandPerson(AddCertificateDTO dto) {

        if (dto.getId() != null) {
            List<CertificatePerson> list = personService.getListByFileIdAndType(dto.getId(), CertificatePerson.NO_HAND);
            if (CollectionUtil.isNotEmpty(list) && dto.getType().equals(CertificateFile.NEED_TYPE)) {
                throw new CustomParameterizedException("当前执行人未执行完毕");
            }
        }
        CertificatePersonInfo certificatePersonInfo = infoService.getById(dto.getHandPersonInfoId());

        //获取执行人信息
        if (certificatePersonInfo == null) {
            throw new CustomParameterizedException("执行人信息不存在");
        }
        CertificatePerson person = new CertificatePerson();
        person.setName(certificatePersonInfo.getName());
        person.setPhone(certificatePersonInfo.getPhone());
        person.setEmail(certificatePersonInfo.getEmail());
        person.setPersonInfoId(dto.getHandPersonInfoId());
        person.setType(CertificatePerson.NORMAL_PERSON);
        //创建连接地址  //创建验证码
        person.setUrl(IdUtil.fastSimpleUUID());
        person.setCode(RandomUtil.randomStringUpper(CODE_LENGTH));
        person.setState(CertificatePerson.NO_HAND);
        person.setUpdateTime(LocalDateTime.now());
        person.setCreateTime(LocalDateTime.now());
        person.setVersion(dto.getHandVersion());
        return person;
    }

    /***
     * 获取文件列表
     * @param admin
     * @param certificateDTO
     * @return
     */
    public PagerVO<CertificateVo> listCetificateFile(Admin admin, CertificateDTO certificateDTO) {
        int page = certificateDTO.getPage();
        int pageSize = certificateDTO.getPageSize();
        if (certificateDTO.getState() != null && certificateDTO.getState().equals(2)) {
            certificateDTO.setState(null);
            certificateDTO.setSelfId(admin.getId());
        }
        //获取项目成员能看到的单
        //获取当前用户拥有的项目
        //获取项目列表
        certificateDTO.setIsAdmin(admin.isAdmin());
        if (!admin.isAdmin()) {
            List<Item> items = itemService.getItemsByAdminId(admin.getId());
//            List<ItemSimpleListVO> items = itemService.getItemsByAdmin(admin);
            if (CollectionUtil.isEmpty(items)) {
                return new PagerVO<>();
            }
            List<Integer> itemIds = items.stream().map(Item::getId).collect(Collectors.toList());
            certificateDTO.setItemIds(itemIds);
        }


        //获取当前登录用户管理的单据
        LambdaQueryWrapper<CertificatePerson> query = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(admin.getTel())) {
            query.eq(CertificatePerson::getPhone, admin.getTel());
        }
        List<CertificatePerson> personList = personService.list(query);
        //获取ids
        List<Integer> cerIds = new ArrayList<>();
        personList.stream().forEach(pr -> {
            if (pr != null && !cerIds.contains(pr.getCerFileid())) {
                cerIds.add(pr.getCerFileid());
            }
        });
        certificateDTO.setCerIds(cerIds);
        Page<CertificateVo> result = PageHelper.startPage(page, pageSize)
                .doSelectPage(() -> baseMapper.listCetificateFile(certificateDTO));

        List<CertificateVo> list = result.getResult();
        if (CollectionUtil.isNotEmpty(list)) {
            //获取 id集合
            List<Integer> ids = list.stream().map(CertificateVo::getId).collect(Collectors.toList());
            //根据id获取最后一位执行人信息
            List<CertificatePerson> persons = personService.getLastListByFileIds(ids);
            //处理执行人信息
            Map<Integer, List<CertificatePerson>> personMap = new HashMap<>();

            if (CollectionUtil.isNotEmpty(persons)) {
                persons.stream().forEach(vo -> {
                    if (vo.getState() > 0) {
                        Integer fileId = vo.getCerFileid();
                        List<CertificatePerson> temp = personMap.get(fileId);
                        if (temp == null) {
                            temp = new ArrayList<>();
                            personMap.put(fileId, temp);
                        }
                        temp.add(vo);
                    }
                });
            }
            list.stream().forEach(vo -> {
                List<CertificatePerson> person = personMap.get(vo.getId());
                if (hasEditPermisson(admin, vo.getItemId())) {
                    vo.setCanOption(true);
                }

                if (vo.getState() != null && vo.getState().equals(CertificateFile.STATE_HANDING) && System.currentTimeMillis() > vo.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()) {
                    //完结该单
//                    baseMapper.compeleteById(vo.getId());
                }

                //如果是自己发起的则可以执行操作
                if (certificateDTO.getType().equals(CertificateFile.CONFIRM_TYPE)) {
                    //获取版本号
                    Double version = vo.getVersion();
                    vo.setName(vo.getName() + "_" + version);
                }

                if (CollectionUtil.isNotEmpty(person)) {
                    vo.setOptions(1);
                    AtomicReference<CertificatePerson> lastPerson = new AtomicReference<>();
                    person.stream().forEach(pp -> {
                        if (pp.getId() != null && pp.getId().equals(vo.getLastHandAdminId())) {
                            vo.setLastHandAdminId(pp.getId());
                            vo.setLastHandAdmin(pp.getName());
                            lastPerson.set(pp);
                        }
                    });

                    //如果是自己发起的则可以执行操作
                    if (certificateDTO.getType().equals(CertificateFile.CONFIRM_TYPE)) {
                        //如果是确认单 自己发起的是可以执行的
                        if (admin != null && admin.getId().equals(vo.getCreateBy())) {
                            vo.setOptions(0);
                            //如果是领导执行的同意则不能修改了
                            if (lastPerson != null) {
                                CertificatePerson temp = lastPerson.get();
                                if (temp != null && temp.getPersonInfoId().equals(vo.getLeaderAdminId()) && temp.getState().equals(CertificatePerson.YES_AGREE)) {
                                    vo.setOptions(1);
                                }

                            }
                        }
                    }

                    //审核通过，且未完结的单是不能修改编辑的
                    if (vo.getCheckStatus() == 1 && vo.getState().equals(CertificateFile.STATE_HANDING)) {
                        vo.setOptions(1);
                    }

                }
            });
        }

        return PagerVO.of(result);
    }

    /**
     * 判断确认单是否有操作权限
     *
     * @return
     */
    private boolean sureFilehasOption(CertificateFile file) {
        if (file != null) {
            //获取所有确认单列表
            LambdaQueryWrapper<CertificateFile> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(CertificateFile::getFileGroupId, file.getFileGroupId());
            queryWrapper.orderByDesc(CertificateFile::getVersion);
            List<CertificateFile> volist = this.list(queryWrapper);
            file = volist.get(0);
            //判断确认单是否是领导完结
            Integer state = file.getState();
            if (state.equals(CertificateFile.STATE_COMPLETE)) {
                Integer handPersonId = file.getHandPersonId();
                CertificatePerson person = personService.getById(handPersonId);
                if (person != null && person.getState().equals(CertificatePerson.YES_AGREE) && person.getType().equals(CertificatePerson.LEADER_PERSON)) {
                    return false;
                }
            }
        } else {
            throw new CustomParameterizedException("确认单不存在");
        }
        return true;
    }


    /***
     * 获取需求单详情
     * @param admin
     * @param id
     * @return
     */
    public CertificateVoDetail cetificateFileDetail(Admin admin, Integer id) {

        //获取需求单详情
        CertificateFile entity = getById(id);
        if (entity == null) {
            throw new CustomParameterizedException("当前单已经不存在");
        }
        Integer type = entity.getType();
        if (CertificateFile.CONFIRM_TYPE.equals(type)) {
            //说明是确认单，获取最新的详情
            //获取所有确认单列表
            LambdaQueryWrapper<CertificateFile> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(CertificateFile::getFileGroupId, entity.getFileGroupId());
            queryWrapper.orderByDesc(CertificateFile::getVersion);
            List<CertificateFile> volist = this.list(queryWrapper);
            id = volist.get(0).getId();
        }
        //获取需求单详情
        CertificateVo certificateFile = baseMapper.getCetificateFileDetail(id);
        if (certificateFile == null) {
            throw new CustomParameterizedException("当前需求单已经不存在");
        }

        CertificateVoDetail vo = new CertificateVoDetail();
        BeanUtils.copyProperties(certificateFile, vo);
        //获取执行人信息
        List<CertificatePerson> list = personService.getListByFileId(id);
        List<CertificatePerson> handList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(list)) {
            list.stream().forEach(member -> {
                if (vo.getHandPersonId().equals(member.getId())) {
                    vo.setHandPersonInfoId(member.getPersonInfoId());
                    vo.setHandPersonName(member.getName());
                }
//                if (member.getState() != CertificatePerson.NO_HAND) {
                handList.add(member);
//                }
            });
        }
        vo.setPersons(handList);
        //获取群组信息
        CertificateGroup group = groupService.getById(certificateFile.getGroupId());
        vo.setGroup(group);

        if (admin != null && admin.isAdmin()) {
            vo.setCanOption(true);
        }
        //获取所有审计成员信息
        List<AdminVO> members = memberService.getMembers(certificateFile.getId());
        members = members.stream().filter(tt -> tt != null).collect(Collectors.toList());
        vo.setMembers(members);
        if (CollectionUtil.isNotEmpty(members)) {
            vo.setAutditPersons(members.stream().map(AdminVO::getId).collect(Collectors.toList()));
        }

        //获取文件信息
        String fileIds = certificateFile.getFileIds();
        if (StrUtil.isNotEmpty(fileIds)) {
            List<CertificateUploadFile> realFiles = getFiles(fileIds);
            vo.setFiles(realFiles);
        }

        //获取抄送人员信息
        List<CertificatePersonInfo> personInfos = getCopyPerson(certificateFile.getCopySendInfoIds());
        vo.setCopySendPersons(personInfos);
        filterHtml(vo);
        return vo;
    }


    /***
     * 获取抄送人员
     * @return
     */
    private List<CertificatePersonInfo> getCopyPerson(String copySendsPersonId) {
        if (StrUtil.isNotEmpty(copySendsPersonId)) {
            String[] personsId = copySendsPersonId.split(",");
            List<Integer> idList = new ArrayList<>();
            Arrays.stream(personsId).forEach(id -> {
                if (StrUtil.isNotEmpty(id)) {
                    try {
                        idList.add(Integer.valueOf(id));
                    } catch (Exception e) {
                        log.error("获取抄送人员", e);
                    }
                }
            });
            if (CollectionUtil.isNotEmpty(idList)) {
                LambdaQueryWrapper<CertificatePersonInfo> query = new LambdaQueryWrapper<>();
                query.in(CertificatePersonInfo::getId, idList);
                return infoService.list(query);
            }
        }
        return null;
    }

    /***
     * 获取文件
     * @param fileIds
     * @return
     */
    public List<CertificateUploadFile> getFiles(String fileIds) {
        if (StrUtil.isEmpty(fileIds)) {
            return new ArrayList<>();
        }
        List<Integer> fIdList = new ArrayList<>();
        Arrays.asList(fileIds.split(",")).stream().forEach(fid -> {
            if (StrUtil.isNotEmpty(fid)) {
                fIdList.add(Integer.valueOf(fid));
            }
        });
        LambdaQueryWrapper<ProjectFile> query = new LambdaQueryWrapper<>();
        query.in(ProjectFile::getId, fIdList);
        List<ProjectFile> files = projectFileService.list(query);

        List<CertificateUploadFile> realFiles = new ArrayList<>();
        files.stream().forEach(f -> {
            CertificateUploadFile file = new CertificateUploadFile();
            file.setId(f.getId() + "");
            file.setName(f.getFileName());
            file.setOriginName(f.getFileName());
            file.setHashKey(f.getHash());
            file.setHost(host);
//            file.setUrl(f.getAllPath());
            file.setUrl("/smartAudit/api/projectFile/download/" + f.getId());
            file.setPath(f.getPath());
            file.setSize(Double.valueOf(f.getSize()));
            file.setExtension(f.getExtName());
            file.setFileMd5(f.getFileMd5());
            realFiles.add(file);
        });

        return realFiles;
    }

    /***
     * 获取人员信息
     * @return
     */
    private Map<Integer, Admin> getUserInfo(List<Integer> adminIds) {
        if (CollectionUtil.isEmpty(adminIds)) {
            return new HashMap<>();
        }
        List<Admin> list = adminService.getAdminsByIds(adminIds);
        Map<Integer, Admin> map = list.stream().collect(Collectors.toMap(Admin::getId, admin -> admin));
        return map;
    }

    /***
     * 获取确认单详情
     * @param admin
     * @param id
     * @return
     */
    public List<CertificateVoDetail> cetificateFileSureDetail(Admin admin, Integer id) {
        //获取需求单详情
        CertificateFile certificateFile = getById(id);
        if (certificateFile == null) {
            throw new CustomParameterizedException("当前确认单已经不存在");
        }
        Integer type = certificateFile.getType();
        if (!CertificateFile.CONFIRM_TYPE.equals(type)) {
//            如果是确认单则需要获取整个流程链路
            throw new CustomParameterizedException("错误的确认单");
        }
        //获取所有确认单列表
        LambdaQueryWrapper<CertificateFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CertificateFile::getFileGroupId, certificateFile.getFileGroupId());
        queryWrapper.orderByAsc(CertificateFile::getVersion);
        List<CertificateVoDetail> volist = baseMapper.cetificateFileSureDetail(certificateFile.getFileGroupId());
        volist.stream().forEach(temVo -> {
            CertificateVoDetail vo = filterHtml(temVo);
            //获取执行人信息
            List<CertificatePerson> list = personService.getListByFileId(vo.getId());
            List<CertificatePerson> handList = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(list)) {
                list.stream().forEach(member -> {
                    if (vo.getHandPersonId() != null && vo.getHandPersonId().equals(member.getId())) {
                        vo.setHandPersonInfoId(member.getPersonInfoId());
                        vo.setHandPersonName(member.getName());
                    }
//                    if (member.getState() != CertificatePerson.NO_HAND) {
                    handList.add(member);
//                    }
                });
            }
            vo.setPersons(handList);
            //获取群组信息
            CertificateGroup group = groupService.getById(vo.getGroupId());
            vo.setGroup(group);

            if (admin != null && admin.isAdmin()) {
                vo.setCanOption(true);
            }
            //获取文件信息
//            LambdaQueryWrapper<CertificateUploadFile> query = new LambdaQueryWrapper<>();
//            query.eq(CertificateUploadFile::getType, CertificateUploadFile.CERTIFICATE_FILE);
//            query.in(CertificateUploadFile::getRelativeId, vo.getId());
            List<CertificateUploadFile> files = getFiles(vo.getFileIds());
            List<CertificatePersonInfo> copyPersonInfos = getCopyPerson(vo.getCopySendInfoIds());
            vo.setCopySendPersons(copyPersonInfos);
            vo.setFiles(files);
            Double version = vo.getVersion();
            vo.setName(vo.getName()  + "_" + version);

        });

        return volist;
    }

    /**
     * 过滤html内容，防xss攻击
     *
     * @param vo
     * @return
     */
    private CertificateVoDetail filterHtml(CertificateVoDetail vo) {
//        info.put("remark", HtmlUtil.filter(remark));
        try {
            String question = vo.getQuestion();
            String content = vo.getContent();
            //使用urldecord解码
            if (StrUtil.isNotEmpty(question)) {
                String questionHtml = URLDecoder.decode(question, "utf-8");
                vo.setQuestion(URLEncoder.encode(HtmlUtil.filter(questionHtml), "utf-8"));
            }
            if (StrUtil.isNotEmpty(content)) {
                String contentHtml = URLDecoder.decode(content, "utf-8");
                vo.setContent(URLEncoder.encode(HtmlUtil.filter(contentHtml), "utf-8"));
            }
        } catch (Exception e) {
            log.error("过滤数据错误", e);
        }
        return vo;
    }

    /***
     * 删除需求单
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteFile(Integer id) {
        CertificateFile file = getById(id);
        if (file == null) {
            throw new CustomParameterizedException("该需求单已经不存在!");
        }
        //删除需求单 需要判断是否有权限，是否已经有执行人
        //TODO 判断删除权限

        //已完结的可以删除
        Integer state = file.getState();
        if (state == CertificateFile.STATE_HANDING) {
            //获取执行人信息
            List<CertificatePerson> persons = personService.getListByFileId(id);
            if (CollectionUtil.isNotEmpty(persons)) {
                boolean flag = persons.stream().anyMatch(vo -> vo.getState() != 0);
                if (flag) {
                    throw new CustomParameterizedException("该单已经在执行中，不能删除!");
                }
            }
        }
        //执行删除
        this.removeById(id);
    }

    /***
     * 执行人登录
     * @param dto
     * @return
     */
    public PersonLoginInfo loginCertificate(CertificatePersonDTO dto) {
        //通过key获取执行人信息ffj
        CertificatePerson person = personService.getPersonByUrl(dto);
        PersonLoginInfo personLoginInfo = getPersonInfo(person);

        //添加校验token  使用执行人key进行url的md5加盐加密
        String token = getHandToken(dto.getCode(), dto.getLoginKey());
        personLoginInfo.setToken(token);
        return personLoginInfo;
    }

    /**
     * 获取登录数据详情
     *
     * @param person
     * @return
     */
    public PersonLoginInfo getPersonInfo(CertificatePerson person) {
        //通过key获取执行人信息ffj
        PersonLoginInfo personLoginInfo = new PersonLoginInfo();
        personLoginInfo.setPersonId(person.getId());
        Integer fileId = person.getCerFileid();
        //获取执行单类型
        CertificateFile file = getById(fileId);
        if (file == null) {
            throw new CustomParameterizedException("执行单不存在");
        }

        Integer type = file.getType();
        personLoginInfo.setType(type);
        if (type.equals(CertificateFile.NEED_TYPE)) {
            CertificateVoDetail certificateVoDetail = cetificateFileDetail(null, fileId);
            if (person.getId() != null && person.getId().equals(file.getHandPersonId()) && CertificateFile.STATE_HANDING.equals(certificateVoDetail.getState())) {
                certificateVoDetail.setCanOption(true);
            }

            personLoginInfo.setVo(certificateVoDetail);
        } else if (type.equals(CertificateFile.CONFIRM_TYPE)) {
            List<CertificateVoDetail> certificateVoDetails = cetificateFileSureDetail(null, fileId);
            if (CollectionUtil.isNotEmpty(certificateVoDetails)) {
                CertificateVoDetail lastVersion = certificateVoDetails.get(0);
                certificateVoDetails.stream().forEach(vo -> {
                            CertificateFile lastHandFile = this.getById(person.getCerFileid());
                            //判断是否是当前执行人
//                            if (person.getId().equals(lastVersion.getHandPersonId()) && person.getState() == CertificatePerson.NO_HAND) {
                            if (person.getId().equals(lastHandFile.getHandPersonId()) && CertificateFile.STATE_HANDING.equals(vo.getState())) {
                                vo.setCanOption(true);
                            }
                        }
                );
            }
            personLoginInfo.setVoList(certificateVoDetails);
        } else {
            throw new CustomParameterizedException("错误的单号");
        }
        //判断是否是第一位执行人
        personLoginInfo.setIsFirst(person.getIsFirst());
        //添加校验token  使用执行人key进行url的md5加盐加密
        return personLoginInfo;
    }

    /**
     * 获取token
     *
     * @param code
     * @param loginKey
     * @return
     */
    public String getHandToken(String code, String loginKey) {
        //创建一个jwt

        MD5 md5 = new MD5(code.getBytes(StandardCharsets.UTF_8));
        String md5Str = md5.digestHex(code);
        String token = tokenProvider.createToken(md5Str);
        return token;
    }

    /***
     * 执行人审批
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    public CertificatePerson handCertificate(CertificateHandDTO dto) {
        CertificatePerson person = fileApproval.ApprovalCertificate(dto);
        if (person != null) {
            try {
                CertificatePerson forwordPerson = person.getForwordPerson();
                if (forwordPerson != null) {
                    //发送短信给对方
//                    egccmService.sendEmsg(forwordPerson.getMsgPhone(), forwordPerson.getCode(), forwordPerson.getUrl());
                    sendMsg(forwordPerson, 0);
                    //发送推送代办
                    PortalPushDTO pushDTO = new PortalPushDTO();
                    pushDTO.setBusiness("todo");
//                    pushDTO.setOwner();
                }
            } catch (Exception e) {
                log.error("发送5G短信失败", e);
            }
        }
        return person;
    }

    /***
     * 执行人审批
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    public CertificatePerson handCertificatePortal(CertificateHandPortalDTO dto) {
        //检验portal人员
        CertificateHandDTO handDto = verifyHandPerson(dto);
        return handCertificate(handDto);
    }

    /***
     * 处理执行人员
     */
    private CertificateHandDTO verifyHandPerson(CertificateHandPortalDTO dto) {
        //说明读取的是portal账号人员
        CertificateHandDTO handDto = new CertificateHandDTO();
        BeanUtils.copyProperties(dto, handDto);
        //获取扭转人员
        String forwordPeronsId = dto.getForwordPersonId();
        CertificatePersonInfo forwordPerson = getPortalUser(forwordPeronsId, dto.getUserType());
        if (forwordPerson != null) {
            handDto.setForwordPersonId(forwordPerson.getId());
        }
        //获取反馈人员
        String feedBackUserId = dto.getFeedBackInfoId();
        CertificatePersonInfo feedBack = getPortalUser(feedBackUserId, dto.getUserType());
        if (feedBack != null) {
            handDto.setFeedBackInfoId(feedBack.getId());
        }
        //获取抄送人员
        String copyIds = dto.getCopySendPersonInfoIds();
        if (StrUtil.isNotEmpty(copyIds)) {
            String[] cpIds = copyIds.split(",");
            StringJoiner sb = new StringJoiner(",");
            Arrays.stream(cpIds).forEach(cpId -> {
                CertificatePersonInfo cpPerson = getPortalUser(cpId, dto.getUserType());
                if (cpPerson != null) {
                    sb.add(cpPerson.getId().toString());
                }
            });
            if (sb.length() > 1) {
                handDto.setCopySendPersonInfoIds(sb.toString());
            }
        }
        return handDto;
    }

    /***
     * 获取系统用户
     * @param userId
     * @return
     */
    private Admin getAdminVo(String userId) {
        Admin admin = adminService.get(Integer.valueOf(userId));
        return admin;
    }


    /***
     * 获取执行人不存在则添加
     * @param userId
     * @return
     */
    private CertificatePersonInfo getPortalUser(String userId, Integer type) {
        if (StrUtil.isEmpty(userId)) {
            return null;
        }

        String nickName, email, telPhone, mobile;
        if (type.equals(0)) {
            LambdaQueryWrapper<PUumUserinfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PUumUserinfo::getUserID, userId);
            PUumUserinfo exsitUser = pUumUserinfoService.getOne(queryWrapper);
            if (exsitUser == null) {
                return null;
            }
            //判断portal用户信息是否已经存在执行人信息当中
            mobile = exsitUser.getTelePhone();
            nickName = exsitUser.getFullName();
            email = exsitUser.getEmail();
        } else {
            Admin admin = getAdminVo(userId);
            mobile = admin.getTel();
            nickName = admin.getNickName();
            email = admin.getEmail();
        }
        CertificatePersonInfo certificatePersonInfo = infoService.getBymobile(mobile);
        if (certificatePersonInfo == null) {
            //添加到执行人信息
            AddHandPersonDTO dto = new AddHandPersonDTO();
            dto.setHandPersonName(nickName);
            dto.setHandPersonEamil(email);
            dto.setHandPersonPhone(mobile);
            certificatePersonInfo = infoService.addPerson(dto);

        }
        return certificatePersonInfo;
    }

    /***
     * 处理单完成
     * @param file
     */
    private void handCerfileState(CertificateFile file) {
        Integer type = file.getType();
        if (type.equals(CertificateFile.CONFIRM_TYPE)) {
            //如果是确认单，则各个吧版本的状态都的设为一样
            LambdaUpdateWrapper<CertificateFile> query = new LambdaUpdateWrapper<>();
            query.set(CertificateFile::getState, file.getState());
            query.eq(CertificateFile::getFileGroupId, file.getFileGroupId());
            this.update(query);
        }
        this.updateById(file);
    }

    /***
     * 管理员执行审批
     * @param file
     * @param admin
     * @param person
     * @return
     */
    private CertificatePerson adminHandCertifi(CertificateFile file, Admin admin, CertificateHandDTO person) {
        CertificatePerson forwordPerson = new CertificatePerson();
        forwordPerson.setName(admin.getNickName());
        forwordPerson.setPhone(admin.getTel());
        forwordPerson.setEmail(admin.getTel());
        forwordPerson.setType(CertificatePerson.ADMIN_PERSON);
        //创建连接地址  //创建验证码
        forwordPerson.setUrl(IdUtil.fastSimpleUUID());
        forwordPerson.setCode(RandomUtil.randomStringUpper(CODE_LENGTH));
        forwordPerson.setState(person.getState());
        forwordPerson.setCerFileid(file.getId());
        forwordPerson.setUpdateTime(LocalDateTime.now());
        forwordPerson.setCreateTime(LocalDateTime.now());
        forwordPerson.setPersonInfoId(admin.getId());
        forwordPerson.setUpdateTime(LocalDateTime.now());
        forwordPerson.setContent(person.getContent());
        forwordPerson.setContent(person.getContent());
        forwordPerson.setState(person.getState());
        personService.save(forwordPerson);
        return forwordPerson;
    }


    /***
     * 用户是否有查看权限
     * @return
     */
    public Boolean hasReadPermission() {

        return true;
    }

    /***
     * 用户是否有操作权限
     * @return
     */
    public Boolean hasOptionsPermission() {

        return true;
    }


    public static void main(String[] args) {
        Class clazz = CertificateVo.class;
        Field[] fields = clazz.getDeclaredFields();
        for (Field f : fields) {

            String name = f.getName();
            TableField tableField = f.getAnnotation(TableField.class);
            if (tableField != null) {
                String tabFiled = tableField.value();
                System.out.println(String.format("<result column=\"%s\" property=\"%s\" />", tabFiled, name));
            }
        }
    }

    /***
     * 编辑
     * @param admin
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    public void editCetificateFile(Admin admin, AddCertificateDTO dto) {
        if (dto.getType().equals(CertificateFile.NEED_TYPE)) {
            //编辑需求单
            addCetificateFile(admin, dto);
        } else {
            //更新该确认单为未完结状态
            //编辑确认单
            CertificateFile file = getById(dto.getId());
            if (file != null) {

                //判断确认单是否是领导完结
                Integer state = file.getState();
                Integer handPersonId = file.getHandPersonId();
                CertificatePerson person = personService.getById(handPersonId);
//                dto.setHandPersonId(handPersonId);
//                dto.setHandPersonInfoId(person.getPersonInfoId());
//                dto.setHandPersonInfoIds(person.getPersonInfoId()+"");
                if (state.equals(CertificateFile.STATE_COMPLETE)) {

                    if (person != null && person.getState().equals(CertificatePerson.YES_AGREE) && person.getType().equals(CertificatePerson.LEADER_PERSON)) {
                        //如果是领导执行同意过则不能再编辑
                        throw new CustomParameterizedException("该单已被领导同意，不能再编辑!");
                    }
                }
                file.setState(CertificateFile.STATE_HANDING);
                this.updateById(file);
            } else {
                throw new CustomParameterizedException("确认单不存在");
            }

            dto.setLastFileId(dto.getId());
            dto.setId(null);
            addCetificateFile(admin, dto);
        }
    }

    /***
     * 是否有编辑权限 超级管理员或者内审管理员有权限
     * @param admin
     * @return
     */
    private boolean hasEditPermisson(Admin admin, Integer itemId) {
        if (admin != null && admin.isAdmin()) {
            return true;
        } else if (admin != null && "R_AUDIT".equals(admin.getRole().getCode())) {
            //如果是内审管理员，判断该管理员是否属于当前项目
            List<Item> list = itemService.getItemsByAdminId(admin.getId());
            if (CollectionUtil.isNotEmpty(list)) {
                boolean flag = list.stream().anyMatch(item -> item.getId().equals(itemId));
                return flag;
            }
        }
        return false;
    }


    /***
     * 执行审核
     * @param admin
     * @param id
     * @param checkStatus
     */
    public void checkedCerFile(Admin admin, Integer id, Integer checkStatus) {
        if (hasCheckouPermission(admin)) {
            CertificateFile file = getById(id);
            file.setCheckStatus(checkStatus);
            if (file == null) {
                throw new CustomParameterizedException("该单不存在");
            }

            String handPersonIds = file.getHandPersonIds();

            if (StrUtil.isEmpty(handPersonIds)) {
                throw new CustomParameterizedException("此单没有添加审核人员");
            }
            String[] personIds = handPersonIds.split(",");

            //添加执行人员，在原单基础上添加多个单
            List<CertificateFile> list = new ArrayList<>();
            int size = personIds.length;
            if (size > 1) {
                for (int i = 0; i < size; i++) {
                    if (i == 0) {
                        file.setName(file.getName() + "001");
                        Integer handPersonId = Integer.valueOf(personIds[i]);
                        AddCertificateDTO dto = new AddCertificateDTO();
                        dto.setHandPersonInfoIds(handPersonIds);
                        dto.setHandPersonInfoId(handPersonId);
                        saveCerFile(file, dto, list);
                    } else {
                        file.setName(file.getName() + "00" + (i + 1));
                        file.setId(null);
                        Integer handPersonId = Integer.valueOf(personIds[i]);
                        AddCertificateDTO dto = new AddCertificateDTO();
                        dto.setHandPersonInfoIds(handPersonIds);
                        dto.setHandPersonInfoId(handPersonId);
                        saveCerFile(file, dto, list);
                    }
                }
            } else if (size == 1) {
                Integer handPersonId = Integer.valueOf(personIds[0]);
                AddCertificateDTO dto = new AddCertificateDTO();
                dto.setHandPersonInfoIds(handPersonIds);
                dto.setHandPersonInfoId(handPersonId);
                saveCerFile(file, dto, list);
            }
            //如果是审核通过则发送5G消息
            if (checkStatus == 1) {
                list.stream().forEach(cer -> {
                    try {
                        //获取执行人
                        CertificatePerson person = personService.getById(cer.getHandPersonId());
                        if (person == null) {
                            log.error("执行人信息不存在");
                        }
//                        egccmService.sendEmsg(person.getPhone(), person.getCode(), person.getUrl());
                        sendMsg(person, 0);
                    } catch (Exception e) {
                        log.error("发送执行人信息失败:", e);
                    }
                    cer.setCheckStatus(checkStatus);
                    this.updateById(cer);

                    //执行抄送信息发送
                    copySendMsg(cer);
                });
            }

        } else {
            throw new CustomParameterizedException("您没有审核权限");
        }
    }


    /***
     * 消息内容类型  0- 执行人信息  1-抄送信息  2-反馈信息 ，3.执行人处理完成通知发起人
     */
    public void sendMsg(CertificatePerson person, Integer msgType) {
        boolean debug = false;
        if (debug) {
//        CertificatePerson person = personService.getById(handPersonId);
            CertificateFile cerFile = this.getById(person.getCerFileid());
            MsgDTO dto = new MsgDTO();
            dto.setCode(person.getCode());
            dto.setLoginKey(person.getUrl());
            dto.setType(cerFile.getType());
            dto.setFileName(cerFile.getName());
            dto.setMsgType(msgType);
            dto.setUrl(egccmService.getCerH5Url(person.getUrl()));
            //获取项目名称
            Integer itemId = cerFile.getItemId();
            try {
                Item item = itemService.get(itemId);
                if (item != null) {
                    dto.setItemName(item.getName());
                }
            } catch (Exception e) {

            }
            egccmService.sendEmsg(person.getPhone(), dto);

            //发送邮件
//        EmailDTO emailDTO = new EmailDTO();
//        Admin admin  = new Admin();

            dto.setUrl(egccmService.getPcUrl(person.getUrl()));
            EmailContent emailContent = emailContentFormat.getEmailContent(dto);
            EmailDTO emailDTO = new EmailDTO();
            emailDTO.setSubject(emailContent.getTitle());
            emailDTO.setContent(emailContent.getContent());
            List<String> to = new ArrayList<>();
//        to.add("576177139@qq.com");
            to.add(person.getEmail());
            emailDTO.setTo(to);

            //获取当前登录用户
            String loginAdminName = SecurityUtils.getCurrentUserLogin();
            Admin admin = adminMapper.findByAccount(loginAdminName);
            if (admin == null) {
                admin = new Admin();
                admin.setId(person.getId());
            }
            emailService.sent(emailDTO, admin);
        }
    }


    /***
     * 格式化内容
     * @return
     */
    private String formatContent(MsgDTO dto) {
        //执行人短信
        String content = "您好！\n" +
                "  %s 的审计%s需您处理。请登录%s  根据实际情况进行回复。验证码为%s。\n" +
                " \n\t广东移动内审部。";

//        0- 执行人信息  1-抄送信息  2-反馈信息
        if (dto.getMsgType() == 1) {
            //抄送短信
            content = "您好！ \n" +
                    "     您的同事正在协助进行%s的审计%s处理工作。可登录%s  进行查阅。验证码为：%s \n" +
                    "\t\n广东移动内审部。";
        } else if (dto.getMsgType() == 2) {
            //反馈短信
            content = "您好！\n" +
                    "     %s 的审计需求%s需咨询您意见。请登录%s  根据实际情况进行回复。验证码为：%s \n" +
                    " \n\t广东移动内审部。";
        } else if (dto.getMsgType() == 3) {
            content = "您好！\n" +
                    "     您的工单%s已经处理完成，请您确认结束。\n" +
                    " \n\t广东移动内审部。";
            return String.format(content, dto.getFileName());
        }
        String realContent = String.format(content, dto.getItemName(), getTypeName(dto.getType()), dto.getUrl(), dto.getCode());
        return realContent;
    }

    /***
     * 获取单类型名称
     * @param type
     * @return
     */
    private String getTypeName(Integer type) {
        if (type == 1) {
            return "需求单";
        } else if (type == 2) {
            return "确认单";
        }
        return "无知单";
    }

    /***
     * 撤回需求单或者确认单，（其实就是结束该单）
     * @param admin
     * @param id
     */
    public void rebackFile(Admin admin, Integer id) {
        CertificateFile certificateFile = getById(id);
        if (certificateFile == null) {
            throw new CustomParameterizedException("该单不存在");
        }
        if (CertificateFile.STATE_COMPLETE.equals(certificateFile.getState())) {
            throw new CustomParameterizedException("该单已完结不能撤回");
        }
        //执行撤回
        certificateFile.setHandStatus(-1);//设置撤回状态
        certificateFile.setState(CertificateFile.STATE_COMPLETE);
        this.updateById(certificateFile);
    }

    /***
     * 发起人完结工单
     * @param admin
     * @param id
     */
    public void compelet(Admin admin, Integer id) {
        CertificateFile certificateFile = getById(id);
        if (certificateFile == null) {
            throw new CustomParameterizedException("该单不存在");
        }
        if (CertificateFile.STATE_COMPLETE.equals(certificateFile.getState())) {
            throw new CustomParameterizedException("该单已完结");
        }
        if (certificateFile.getState() != null && certificateFile.getState() == 2) {
            if (admin.isAdmin() || admin.getId().equals(certificateFile.getAdminId())) {
                certificateFile.setState(CertificateFile.STATE_COMPLETE);
                this.updateById(certificateFile);
            } else {
                throw new CustomParameterizedException("您没有权限完结该单");
            }
        } else {
            throw new CustomParameterizedException("该单未在待完结状态");
        }

    }

    /**
     * 获取h5详情
     *
     * @param admin
     * @return
     */
    public PersonLoginInfo wapDetail(Admin admin, Integer id) {
        if (id == null) {
            throw new CustomParameterizedException("请输入正确的id");
        }
        CertificateVo certificateFile = baseMapper.getCetificateFileDetail(id);
        if (certificateFile == null) {
            throw new CustomParameterizedException("该单不存在");
        }
        String mobile = certificateFile.getHandPersonPhone();

        String tel = admin.getTel();
        if (tel.equals(mobile)) {
            //如果是当前执行人
            LambdaQueryWrapper<CertificatePerson> query = new LambdaQueryWrapper<>();
            if (StrUtil.isNotEmpty(tel)) {
                query.eq(CertificatePerson::getPhone, tel);
                query.eq(CertificatePerson::getCerFileid, id);
            }
            List<CertificatePerson> list = personService.list(query);
            if (CollectionUtil.isEmpty(list)) {
                throw new CustomParameterizedException("执行人不存在");
            }
            AtomicReference<CertificatePerson> person = new AtomicReference<>();
            list.stream().forEach(cer -> {
                if (id.equals(cer.getCerFileid())) {
                    person.set(cer);
                }
            });

            PersonLoginInfo personLoginInfo = getPersonInfo(person.get());
            //添加校验token  使用执行人key进行url的md5加盐加密
            String token = getHandToken(person.get().getCode(), person.get().getUrl());
            personLoginInfo.setToken(token);
            return personLoginInfo;
        } else {

//            //把当前用户添加到执行人
            CertificatePersonInfo personInfo = infoService.getBymobile(mobile);
            if (personInfo == null) {
                //添加到执行人信息
                AddHandPersonDTO dto = new AddHandPersonDTO();
                dto.setHandPersonName(admin.getNickName());
                dto.setHandPersonEamil(admin.getEmail());
                dto.setHandPersonPhone(admin.getTel());
                personInfo = infoService.addPerson(dto);
            }
            // 添加到该执行人关联到该单
            CertificatePerson person = personService.addInfoToCer(personInfo, certificateFile);
            PersonLoginInfo personLoginInfo = getPersonInfo(person);


            //添加校验token  使用执行人key进行url的md5加盐加密
            String token = getHandToken(person.getCode(), person.getUrl());
            personLoginInfo.setToken(token);
            return personLoginInfo;
        }
    }
}
